package com.mengniu.commerce.sync.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mengniu.commerce.common.core.domain.R;
import com.mengniu.commerce.common.core.enums.ModuleEnum;
import com.mengniu.commerce.common.core.enums.PushStatus;
import com.mengniu.commerce.common.core.enums.SourceEnum;
import com.mengniu.commerce.common.core.utils.IdGeneratorSnowflake;
import com.mengniu.commerce.common.core.utils.bean.BeanUtils;
import com.mengniu.commerce.common.template.enums.APIUrlEnum;
import com.mengniu.commerce.sync.api.base.MnResult;
import com.mengniu.commerce.sync.api.base.OrderResult;
import com.mengniu.commerce.sync.api.domain.CreateOrderModel;
import com.mengniu.commerce.sync.api.domain.ExtModel;
import com.mengniu.commerce.sync.api.domain.ModifyOrderModel;
import com.mengniu.commerce.sync.api.dto.RetryDTO;
import com.mengniu.commerce.sync.common.utils.MnResultUtil;
import com.mengniu.commerce.sync.common.utils.RestTemplateUtil;
import com.mengniu.commerce.sync.exception.RetryException;
import com.mengniu.commerce.sync.mapper.OrderInfoMapper;
import com.mengniu.commerce.sync.mapper.OrderItemMapper;
import com.mengniu.commerce.sync.model.MnOrderInfoModel;
import com.mengniu.commerce.sync.model.MnOrderItemModel;
import com.mengniu.commerce.sync.service.OrderService;
import com.mengniu.commerce.sync.utils.RetryUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.RetryContext;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.support.RetrySynchronizationManager;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    public static final String baseURL = "https://t-openapi-gateway.mengniu.cn/";
    @Resource
    private RestTemplateUtil restTemplateUtil;

    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private RetryUtils retryUtils;

    /**
     * F-C消费者电商平台订单创建API-原子
     */
    @Override
    @Retryable(value = { RetryException.class }, maxAttempts = 8, backoff = @Backoff(delay = 10000))
    public R createOrder(List<CreateOrderModel> createOrderModelList, RetryDTO retryDTO) {
        log.info("消费者销售订单创建入参为{}_{}", JSONObject.toJSONString(createOrderModelList),retryDTO);
        JSONObject param = (JSONObject) JSON.toJSON(createOrderModelList);
        log.info("调用蒙牛消费者销售订单创建入参数为{}",JSONObject.toJSONString(param));
        RetryContext context = RetrySynchronizationManager.getContext();
        log.info("当前消费者销售订单创建重试次数{}",JSONObject.toJSONString(context));
        JSONObject result = new JSONObject();
        try{
            result = restTemplateUtil.doPost(param, baseURL + APIUrlEnum.CREATE_ORDER.getPath());
        }catch (Exception e){
            log.error("调用蒙牛消费者销售订单创建接口失败",e);
            Long id = retryUtils.insertOrUpdate(param, retryDTO.getSource(), retryDTO.getStoreName(), ModuleEnum.ORDER.getModuleName(), APIUrlEnum.CREATE_ORDER.getMethod(), context.getRetryCount(), e.getMessage(),retryDTO.getRetryId());
            retryDTO.setRetryId(id);
            throw new RetryException("发生了重试异常{}", e);
        }
        OrderResult orderResult = JSONObject.parseObject(result.toJSONString(), OrderResult.class);
        log.info("调用蒙牛消费者销售订单创建响应转换为orderResult{}",JSONObject.toJSONString(orderResult));
        if (Objects.isNull(orderResult) || !orderResult.getSuccess()){
            return R.fail(result,"调用蒙牛接口失败");
        }
        List<OrderResult.DataModel> errorData = Optional.ofNullable(orderResult.getData()).map(OrderResult.ResultData::getErrorData).orElse(new ArrayList<>());
        //创建失败的订单也落库。后续重推再修改子单号和蒙牛订单号
        List<OrderResult.DataModel> successData = Optional.ofNullable(orderResult.getData()).map(OrderResult.ResultData::getSuccessData).orElse(new ArrayList<>());
        this.insertOrder(successData,createOrderModelList,retryDTO.getSource(),true);
        this.insertOrder(errorData,createOrderModelList,retryDTO.getSource(),false);
        return R.ok(result);
    }

    /**
     * F-C消费者销售订单修改API-原子
     */
    @Override
    @Retryable(value = { RetryException.class }, maxAttempts = 8, backoff = @Backoff(delay = 10000))
    public R  modifyOrder(List<ModifyOrderModel> modifyOrderModelList,RetryDTO retryDTO) {
        log.info("消费者销售订单修改入参为{}",JSONObject.toJSONString(modifyOrderModelList));
        JSONObject param = (JSONObject) JSON.toJSON(modifyOrderModelList);
        log.info("调用蒙牛消费者销售订单修改入参数为{}",JSONObject.toJSONString(param));
        RetryContext context = RetrySynchronizationManager.getContext();
        log.info("当前消费者销售订单修改重试次数{}",JSONObject.toJSONString(context));
        JSONObject result = new JSONObject();
        try{
            result = restTemplateUtil.doPost(param, baseURL + APIUrlEnum.MODIFY_ORDER.getPath());
            log.info("调用蒙牛消费者销售修改创建响应为{}",JSONObject.toJSONString(result));
        }catch (Exception e){
            log.error("调用蒙牛消费者销售订单修改接口失败",e);
            Long id = retryUtils.insertOrUpdate(param, retryDTO.getSource(), retryDTO.getStoreName(), ModuleEnum.ORDER.getModuleName(), APIUrlEnum.MODIFY_ORDER.getMethod(), context.getRetryCount(), e.getMessage(),retryDTO.getRetryId());
            retryDTO.setRetryId(id);
            throw new RetryException("发生了重试异常{}", e);
        }
        OrderResult orderResult = JSONObject.parseObject(result.toJSONString(), OrderResult.class);
        log.info("调用蒙牛消费者销售订单修改响应转换为orderResult{}",JSONObject.toJSONString(orderResult));
        if (Objects.isNull(orderResult) || !orderResult.getSuccess()){
            return R.fail(result,"调用蒙牛接口失败");
        }
        List<OrderResult.DataModel> errorData = orderResult.getData().getErrorData();
        List<OrderResult.DataModel> successData = orderResult.getData().getSuccessData();
        this.updateOrder(errorData,modifyOrderModelList,true);
        this.updateOrder(successData,modifyOrderModelList,false);
        return R.ok(result);
    }

    public void updateOrder(List<OrderResult.DataModel> dataModelList, List<ModifyOrderModel> modifyOrderModelList, Boolean isSuccess) {
        dataModelList.forEach(dataModel -> {
            String salesOrderNo = dataModel.getSalesOrderNo();
            MnOrderInfoModel mnOrderInfoModel = orderInfoMapper.selectByOrderNo(salesOrderNo,null,null);
            modifyOrderModelList.stream()
                    .filter(modifyOrderModel -> modifyOrderModel.getSalesOrderNo().equals(salesOrderNo))
                    .findFirst()
                    .ifPresent(orderModel -> {
                        this.updateMnOrderModel(mnOrderInfoModel,orderModel,isSuccess);
                        orderInfoMapper.updateOrderInfo(mnOrderInfoModel);
                    });
        });
    }

    public void updateMnOrderModel(MnOrderInfoModel mnOrderInfoModel, ModifyOrderModel orderModel, Boolean isSuccess) {
        if (isSuccess){
            mnOrderInfoModel.setPushStatus(PushStatus.UPDATE_SUCCESS.getStatus());
        }else {
            mnOrderInfoModel.setPushStatus(PushStatus.UPDATE_ERROR.getStatus());
        }
        BeanUtils.copyProperties(mnOrderInfoModel,orderModel);
    }


    public void insertOrder(List<OrderResult.DataModel> dataModelList, List<CreateOrderModel> createOrderModelList, String source,Boolean isSuccess) {
        dataModelList.forEach(dataModel -> {
            String sourceOrderNo = dataModel.getSourceOrderNo();
            createOrderModelList.stream()
                    .filter(createOrderModel -> createOrderModel.getSourceOrderNo().equals(sourceOrderNo))
                    .findFirst()
                    .ifPresent(orderModel -> {
                        MnOrderInfoModel mnOrderModel = this.createMnOrderModel(orderModel, dataModel, source,isSuccess);
                        List<MnOrderItemModel> mnOrderItemModelList = this.createMnOrderItemModel(orderModel,dataModel,isSuccess);
                        log.info("创建蒙牛订单落库数据mnOrderModel和mnOrderItemModelList分别为{}_{}",JSONObject.toJSONString(mnOrderModel),JSONObject.toJSONString(mnOrderItemModelList));
                        orderInfoMapper.insertOrderInfo(mnOrderModel);
                        mnOrderItemModelList.forEach(mnOrderItemModel -> orderItemMapper.insertOrderItem(mnOrderItemModel));
                    });
        });

    }

    public List<MnOrderItemModel> createMnOrderItemModel(CreateOrderModel orderModel, OrderResult.DataModel dataModel,Boolean isSuccess) {
        List<MnOrderItemModel> mnOrderItemModelList = new ArrayList<>();
        List<CreateOrderModel.OrderItem> orderItemList = orderModel.getOrderItemList();
        for (int i = 0; i < orderItemList.size(); i++) {
            CreateOrderModel.OrderItem o = orderItemList.get(i);
            OrderResult.OrderItem orderItem = dataModel.getOrderItems().get(i);
            MnOrderItemModel mnOrderItemModel = new MnOrderItemModel();
            mnOrderItemModel.setId(new IdGeneratorSnowflake().snowflakeId());
            BeanUtils.copyProperties(mnOrderItemModel,o);
            if (isSuccess){
                mnOrderItemModel.setMnOrderNo(dataModel.getSalesOrderNo());
                mnOrderItemModel.setSourceOrderNo(orderModel.getSourceOrderNo());
                mnOrderItemModel.setOrderItemLogisticInfo(orderItem.getOrderItemLogistics() + "" );
                mnOrderItemModel.setOrderItemActivityInfo(orderItem.getOrderItemActivities() + "" );
            }else {
                mnOrderItemModel.setMnOrderNo("CREATE_ORDER_ERROR");
                mnOrderItemModel.setSourceOrderNo(orderModel.getSourceOrderNo());
            }
//            mnOrderItemModel.setBuyItemNo(o.getBuyItemNo());
//            mnOrderItemModel.setGiftFlag(o.getGiftFlag());
//            mnOrderItemModel.setInnerProductCode(o.getInnerProductCode());
//            mnOrderItemModel.setInnerProductName(o.getInnerProductName());
//            mnOrderItemModel.setNote(o.getNote());
//            mnOrderItemModel.setPlannedDeliveryTime(o.getPlannedDeliveryTime());
//            mnOrderItemModel.setProductBarCode(o.getProductBarCode());
//            mnOrderItemModel.setProductQuantity(o.getProductQuantity());
//            mnOrderItemModel.setItemPromotionAmount(o.getItemPromotionAmount());
//            mnOrderItemModel.setSalesUnitCode(o.getSalesUnitCode());
//            mnOrderItemModel.setSalesUnitName(o.getSalesUnitName());
//            mnOrderItemModel.setSourceOrderItemNo(o.getSourceOrderItemNo());
//            mnOrderItemModel.setStockUnitCode(o.getStockUnitCode());
//            mnOrderItemModel.setStockUnitName(o.getStockUnitName());
//            mnOrderItemModel.setStockConversionNum(o.getStockConversionNum());
//            mnOrderItemModel.setTotalAmount(o.getTotalAmount());
//            mnOrderItemModel.setUnitConversionRelationship(o.getUnitConversionRelationship());
//            mnOrderItemModel.setUnitPrice(o.getUnitPrice());
            ExtModel extModel = new ExtModel(o.getExt1(),o.getExt2(),o.getExt3(),o.getExt4(),o.getExt5(),o.getExt6(),o.getExt7(),o.getExt8(),o.getExt9(),o.getExt10());
            mnOrderItemModel.setExt(extractFieldsAsList(extModel) + "");
            mnOrderItemModel.setCreateTime(new Date());
            mnOrderItemModelList.add(mnOrderItemModel);
        }
        return mnOrderItemModelList;
    }

    public MnOrderInfoModel createMnOrderModel(CreateOrderModel orderModel, OrderResult.DataModel dataModel, String source,Boolean isSuccess) {
        MnOrderInfoModel mnOrderInfoModel = new MnOrderInfoModel();
        mnOrderInfoModel.setId(new IdGeneratorSnowflake().snowflakeId());
        if (source.equals(SourceEnum.YZ.getSource())){
            mnOrderInfoModel.setYzOrderNo(orderModel.getSourceOrderNo());
        }
        if (source.equals(SourceEnum.WM.getSource())){
            mnOrderInfoModel.setWmOrderNo(orderModel.getSourceOrderNo());
        }
        if (isSuccess){
            mnOrderInfoModel.setMnOrderNo(dataModel.getSalesOrderNo());
            mnOrderInfoModel.setPushStatus(PushStatus.CREATE_SUCCESS.getStatus());
        }else {
            mnOrderInfoModel.setMnOrderNo("CREATE_ORDER_ERROR");
            mnOrderInfoModel.setPushStatus(PushStatus.CREATE_ERROR.getStatus());
        }
        BeanUtils.copyProperties(mnOrderInfoModel,orderModel);
//        mnOrderInfoModel.setBanner(orderModel.getBanner());
//        mnOrderInfoModel.setBusinessType(orderModel.getBusinessType());
//        mnOrderInfoModel.setBusinessTypeName(orderModel.getBusinessTypeName());
//        mnOrderInfoModel.setBusinessUnitCode(orderModel.getBusinessUnitCode());
//        mnOrderInfoModel.setBuyerAccount(orderModel.getBuyerAccount());
//        mnOrderInfoModel.setBuyerNote(orderModel.getBuyerNote());
//        mnOrderInfoModel.setConfirmReceiptTime(orderModel.getConfirmReceiptTime());
//        mnOrderInfoModel.setDeliveryAddressDetail(orderModel.getDeliveryAddressDetail());
//        mnOrderInfoModel.setFreightAmount(orderModel.getFreightAmount());
//        mnOrderInfoModel.setNote(orderModel.getNote());
//        mnOrderInfoModel.setFromSys(orderModel.getFromSys());
//        mnOrderInfoModel.setPaidAmount(orderModel.getPaidAmount());
//        mnOrderInfoModel.setPayableAmount(orderModel.getPayableAmount());
//        mnOrderInfoModel.setPostalCode(orderModel.getPostalCode());
//        mnOrderInfoModel.setPromotionAmount(orderModel.getPromotionAmount());
//        mnOrderInfoModel.setReceiverName(orderModel.getReceiverName());
//        mnOrderInfoModel.setReceiverPhone(orderModel.getReceiverPhone());
//        mnOrderInfoModel.setReceivingCityCode(orderModel.getReceivingCityCode());
//        mnOrderInfoModel.setReceivingCityName(orderModel.getReceivingCityName());
//        mnOrderInfoModel.setReceivingCountryCode(orderModel.getReceivingCountryCode());
//        mnOrderInfoModel.setReceivingCountryName(orderModel.getReceivingCountryName());
//        mnOrderInfoModel.setReceivingDistrictCode(orderModel.getReceivingDistrictCode());
//        mnOrderInfoModel.setReceivingDistrictName(orderModel.getReceivingDistrictName());
//        mnOrderInfoModel.setReceivingProvinceCode(orderModel.getReceivingProvinceCode());
//        mnOrderInfoModel.setReceivingProvinceName(orderModel.getReceivingProvinceName());
//        mnOrderInfoModel.setReceivingStreetCode(orderModel.getReceivingStreetCode());
//        mnOrderInfoModel.setReceivingStreetName(orderModel.getReceivingStreetName());
//        mnOrderInfoModel.setSalesOrderType(orderModel.getSalesOrderType());
//        mnOrderInfoModel.setShipTime(orderModel.getShipTime());
//        mnOrderInfoModel.setSourceOrderNo(orderModel.getSourceOrderNo());
//        mnOrderInfoModel.setStoreCode(orderModel.getStoreCode());
//        mnOrderInfoModel.setStoreName(orderModel.getStoreName());
//        mnOrderInfoModel.setSourceCreateTime(orderModel.getSourceCreateTime());
        ExtModel extModel = new ExtModel(orderModel.getExt1(),orderModel.getExt2(),orderModel.getExt3(),orderModel.getExt4(),orderModel.getExt5(),orderModel.getExt6(),orderModel.getExt7(),orderModel.getExt8(),orderModel.getExt9(),orderModel.getExt10());
        mnOrderInfoModel.setExt(extractFieldsAsList(extModel) + "");
        mnOrderInfoModel.setCreateTime(new Date());
        return mnOrderInfoModel;
    }


    public List<String> extractFieldsAsList(ExtModel extModel) {
        List<String> fieldValues = new ArrayList<>();
        Field[] fields = extModel.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object value = field.get(extModel);
                if (value != null) {
                    fieldValues.add(value.toString());
                } else {
                    fieldValues.add(null); // or you can add an empty string ""
                }
            } catch (IllegalAccessException e) {
                log.error("extractFieldsAsList异常",e);
            }
        }
        return fieldValues;
    }
}
